package com.clhbolg.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.file.FileNameUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clhbolg.domain.Photo;
import com.clhbolg.domain.PhotoAlbum;
import com.clhbolg.domain.bo.PhotoBo;
import com.clhbolg.domain.vo.PhotoVo;
import com.clhbolg.enums.FilePathEnum;
import com.clhbolg.mapper.PhotoAlbumMapper;
import com.clhbolg.mapper.PhotoMapper;
import com.clhbolg.model.vo.request.*;
import com.clhbolg.service.IPhotoService;
import com.clhbolg.strategy.context.UploadStrategyContext;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 照片Service业务层处理
 *
 * @author cailinhu
 * @date 2023-02-08
 */
@RequiredArgsConstructor
@Service
@DS("slave")
public class PhotoServiceImpl implements IPhotoService {

    private final PhotoMapper baseMapper;

    @Autowired
    UploadStrategyContext uploadStrategyContext;

    @Resource
    PhotoAlbumMapper photoAlbumMapper;

    /**
     * 查询照片
     */
    @Override
    public PhotoVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询照片列表
     */
    @Override
    public TableDataInfo<PhotoVo> queryPageList(PhotoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Photo> lqw = buildQueryWrapper(bo);
        Page<PhotoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询照片列表
     */
    @Override
    public List<PhotoVo> queryList(PhotoBo bo) {
        LambdaQueryWrapper<Photo> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Photo> buildQueryWrapper(PhotoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Photo> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getAlbumId() != null, Photo::getAlbumId, bo.getAlbumId());
        lqw.like(StringUtils.isNotBlank(bo.getPhotoName()), Photo::getPhotoName, bo.getPhotoName());
        lqw.eq(StringUtils.isNotBlank(bo.getPhotoDesc()), Photo::getPhotoDesc, bo.getPhotoDesc());
        lqw.eq(StringUtils.isNotBlank(bo.getPhotoSrc()), Photo::getPhotoSrc, bo.getPhotoSrc());
        lqw.eq(bo.getIsDelete() != null, Photo::getIsDelete, bo.getIsDelete());
        return lqw;
    }

    /**
     * 新增照片
     */
    @Override
    public Boolean insertByBo(PhotoBo bo) {
        Photo add = BeanUtil.toBean(bo, Photo.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改照片
     */
    @Override
    public Boolean updateByBo(PhotoBo bo) {
        Photo update = BeanUtil.toBean(bo, Photo.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Photo entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除照片
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public TableDataInfo listPhotos(ConditionVO conditionVO, PageQuery pageQuery) {
        LambdaQueryWrapper<Photo> wrapper = Wrappers.lambdaQuery(Photo.class)
            .eq(Photo::getIsDelete, conditionVO.getIsDelete())
            .eq(Objects.nonNull(conditionVO.getAlbumId()),Photo::getAlbumId,conditionVO.getAlbumId())
            .orderByDesc(BaseEntity::getCreateTime);
        Page<Photo> photoPage = baseMapper.selectPage(pageQuery.build(), wrapper);
        return TableDataInfo.build(photoPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePhotos(PhotosVO photos) {
        //先上传？
        List<MultipartFile> files = photos.getFiles();
        List<Photo> photoList=new ArrayList<>(files.size());
        for (MultipartFile file : files) {
            String url=uploadStrategyContext.executeUploadStrategy(file, FilePathEnum.PHOTO.getPath());
            Photo photo = new Photo();
            photo.setAlbumId(photos.getAlbumId());
            photo.setPhotoName(IdWorker.getIdStr());
            photo.setPhotoSrc(url);
            photoList.add(photo);
        }
        //存数据库？
        baseMapper.insertBatch(photoList);
    }

    @Override
    public void updatePhoto(PhotoInfoVO photoInfoVO) {
        Photo photo = BeanUtil.copyProperties(photoInfoVO, Photo.class);
        baseMapper.updateById(photo);
    }

    @Override
    public void updatePhotosAlbum(PhotoVO photoVO) {
        List<Photo> photoList = photoVO.getPhotoIds().stream().map(item -> Photo.builder()
                .id(item)
                .albumId(photoVO.getAlbumId())
                .build())
            .collect(Collectors.toList());
        baseMapper.updateBatchById(photoList);
    }

    @Override
    public void DeleteOrRecoverPhotos(DeleteVO deleteVO) {
        List<Photo> photoList = deleteVO.getIds().stream().map(item -> Photo.builder()
                .id(item)
                .isDelete(deleteVO.getIsDelete())
                .build())
            .collect(Collectors.toList());
        baseMapper.updateBatchById(photoList);
        //恢复相册
        if (deleteVO.getIsDelete()==0){
            //获得所有的相册id
            List<Photo> photos = baseMapper.selectList(Wrappers.lambdaQuery(Photo.class).select(Photo::getAlbumId).in(Photo::getId, deleteVO.getIds()).groupBy(Photo::getAlbumId));
            List<PhotoAlbum> photoAlbumList = photos.stream().map(e ->
                PhotoAlbum.builder().id(e.getAlbumId()).isDelete(deleteVO.getIsDelete()).build()
            ).collect(Collectors.toList());
            photoAlbumMapper.updateBatchById(photoAlbumList);
        }

    }

    /**
     * 真实删除相片
     *
     *
     * @param photoIds
     */
    @Override
    public void deletePhotos(List<Long> photoIds) {
        //1、获取到图片网络地址
        List<Object> photosSrc = baseMapper.selectObjs(Wrappers.lambdaQuery(Photo.class).select(Photo::getPhotoSrc).in(Photo::getId,photoIds));
        //1、删除数据库
        baseMapper.deleteBatchIds(photoIds);
        /**
         * 删除空相册的正确逻辑：
         *   1、先查询出未删除前的相片对应的相册id
         *   2、删除后，再去数据库中找到没有相片的相册
         *   3、对比id，再删除相册
         *   4、未写的原因：（感觉不太实用，如果我保留该相册怎么说？）
         */

        /*
        逻辑不对，不能删除空相册
        //2、查询被删除的相片所属相册是否还存在其他相片
        //    如果没有其他相片那就把相册一起删除
        List<NullAlbumDTO> list=baseMapper.selectNullAlbum();
        List<Long> collect = list.stream().map(NullAlbumDTO::getId).collect(Collectors.toList());
        List<String> picAddr = list.stream().map(NullAlbumDTO::getAlbumCover).collect(Collectors.toList());
        photoAlbumMapper.deleteBatchIds(collect);
        photosSrc.addAll(picAddr);
         */
        //2、删除阿里云
        for (Object o : photosSrc) {
            String name = FileNameUtil.getName(o.toString());
            uploadStrategyContext.executeDeleteStrategy(FilePathEnum.PHOTO.getPath()+name);
        }

    }


}
